// compatibility_bridge.cpp
#include "compatibility_bridge.h"
#include <wx/xml/xml.h>
#include <wx/file.h>
#include <wx/textfile.h>
#include <wx/tokenzr.h>

namespace cbConfig {

CompatibilityBridge& CompatibilityBridge::Get() {
    static CompatibilityBridge instance;
    return instance;
}

CompatibilityBridge::CompatibilityBridge() {
    InitializeMappings();
}

void CompatibilityBridge::InitializeMappings() {
    // 映射表在静态方法中实现，这里初始化其他资源
}

// VC++ 配置映射实现
BuildVariant CompatibilityBridge::VCMapping::ConfigToVariant(const wxString& config) {
    wxString lower = config.Lower();
    if (lower.Contains("debug")) return BuildVariant::DEBUG;
    if (lower.Contains("release")) return BuildVariant::RELEASE;
    if (lower.Contains("minsize")) return BuildVariant::SIZE_OPTIMIZED;
    if (lower.Contains("profile")) return BuildVariant::PROFILE;
    return BuildVariant::DEVELOPER;
}

wxString CompatibilityBridge::VCMapping::VariantToConfig(BuildVariant variant) {
    switch (variant) {
        case BuildVariant::DEBUG: return "Debug";
        case BuildVariant::RELEASE: return "Release";
        case BuildVariant::SIZE_OPTIMIZED: return "MinSizeRel";
        case BuildVariant::PROFILE: return "Profile";
        default: return "Release";
    }
}

ArchBits CompatibilityBridge::VCMapping::PlatformToArch(const wxString& platform) {
    wxString lower = platform.Lower();
    if (lower == "win32") return ArchBits::BITS_32;
    if (lower == "x64") return ArchBits::BITS_64;
    if (lower == "arm64") return ArchBits::BITS_ARM64;
    if (lower == "arm") return ArchBits::BITS_ARM64;
    return ArchBits::BITS_32;
}

wxString CompatibilityBridge::VCMapping::ArchToPlatform(ArchBits arch) {
    switch (arch) {
        case ArchBits::BITS_32: return "Win32";
        case ArchBits::BITS_64: return "x64";
        case ArchBits::BITS_ARM64: return "ARM64";
        default: return "Win32";
    }
}

// Code::Blocks 配置映射实现
BuildVariant CompatibilityBridge::CBMapping::BuildTypeToVariant(const wxString& buildType) {
    wxString lower = buildType.Lower();
    if (lower.Contains("debug")) return BuildVariant::DEBUG;
    if (lower.Contains("release")) return BuildVariant::RELEASE;
    return BuildVariant::DEVELOPER;
}

wxString CompatibilityBridge::CBMapping::VariantToBuildType(BuildVariant variant) {
    switch (variant) {
        case BuildVariant::DEBUG: return "debug";
        case BuildVariant::RELEASE: return "release";
        default: return "debug";
    }
}

Toolchain CompatibilityBridge::CBMapping::CompilerIdToToolchain(const wxString& compilerId) {
    wxString lower = compilerId.Lower();
    if (lower == "msvc" || lower == "msvctoolkit") return Toolchain::MSVC;
    if (lower == "gcc") return Toolchain::GCC;
    if (lower == "clang") return Toolchain::CLANG;
    if (lower == "mingw") return Toolchain::MINGW;
    if (lower.Contains("arm")) return Toolchain::ARM_GCC;
    if (lower.Contains("riscv")) return Toolchain::RISCV_GCC;
    return Toolchain::GCC;
}

wxString CompatibilityBridge::CBMapping::ToolchainToCompilerId(Toolchain toolchain) {
    switch (toolchain) {
        case Toolchain::MSVC: return "msvc";
        case Toolchain::GCC: return "gcc";
        case Toolchain::CLANG: return "clang";
        case Toolchain::MINGW: return "mingw";
        case Toolchain::ARM_GCC: return "arm-gcc";
        case Toolchain::RISCV_GCC: return "riscv-gcc";
        default: return "gcc";
    }
}

// 项目文件自动检测和转换
BuildProfile CompatibilityBridge::FromProjectFile(const wxString& projectFile) {
    wxString format = DetectProjectFormat(projectFile);
    
    if (format == "vcxproj") {
        return FromVCProject(projectFile);
    } else if (format == "cbp") {
        return FromCBProject(projectFile);
    } else if (format == "cmake") {
        return FromCMake(projectFile);
    }
    
    // 默认返回基础配置
    BuildProfile profile;
    profile.name = "Default";
    profile.SyncToLegacy();
    return profile;
}

wxString CompatibilityBridge::DetectProjectFormat(const wxString& projectFile) {
    wxString ext = wxFileName(projectFile).GetExt().Lower();
    
    if (ext == "vcxproj") return "vcxproj";
    if (ext == "cbp") return "cbp";
    if (ext == "cmake" || ext == "cmakelists.txt") return "cmake";
    if (ext == "pro" || ext == "pri") return "qmake";
    if (ext == "sln") return "sln";
    
    // 通过文件内容检测
    wxTextFile file;
    if (file.Open(projectFile)) {
        wxString firstLine = file.GetFirstLine();
        if (firstLine.Contains("<?xml")) {
            if (firstLine.Contains("Project")) return "vcxproj";
            if (firstLine.Contains("CodeBlocks_project_file")) return "cbp";
        }
        if (firstLine.Contains("cmake_minimum_required")) return "cmake";
    }
    
    return "unknown";
}

// VC++ 项目解析（详细实现）
BuildProfile CompatibilityBridge::FromVCProject(const wxString& vcxprojFile) {
    BuildProfile profile;
    profile.name = wxFileName(vcxprojFile).GetName();
    
    wxXmlDocument doc;
    if (!doc.Load(vcxprojFile)) {
        return profile; // 返回默认配置
    }
    
    wxXmlNode* root = doc.GetRoot();
    if (!root || root->GetName() != "Project") {
        return profile;
    }
    
    // 遍历所有 PropertyGroup
    wxXmlNode* child = root->GetChildren();
    while (child) {
        if (child->GetName() == "PropertyGroup") {
            wxString condition = child->GetAttribute("Condition", "");
            
            // 提取配置和平台
            wxString config = ExtractVCConfiguration(condition);
            wxString platform = ExtractVCPlatform(condition);
            
            if (!config.empty() && !platform.empty()) {
                profile.legacy.vcConfiguration = config;
                profile.legacy.vcPlatform = platform;
                
                // 解析具体设置
                wxXmlNode* prop = child->GetChildren();
                while (prop) {
                    wxString propName = prop->GetName();
                    wxString propValue = prop->GetNodeContent();
                    
                    if (propName == "ConfigurationType") {
                        profile.legacy.outputFilename = propValue;
                    } else if (propName == "PlatformToolset") {
                        profile.legacy.vcToolset = propValue;
                    } else if (propName == "CharacterSet") {
                        profile.legacy.vcCharacterSet = propValue;
                    } else if (propName == "RuntimeLibrary") {
                        profile.legacy.vcRuntime = propValue;
                    }
                    
                    prop = prop->GetNext();
                }
                break; // 找到第一个有效配置就退出
            }
        }
        child = child->GetNext();
    }
    
    // 从传统字段同步到正交属性
    profile.SyncFromLegacy();
    return profile;
}

// Code::Blocks 项目解析
BuildProfile CompatibilityBridge::FromCBProject(const wxString& cbProjectFile) {
    BuildProfile profile;
    profile.name = wxFileName(cbProjectFile).GetName();
    
    wxXmlDocument doc;
    if (!doc.Load(cbProjectFile)) {
        return profile;
    }
    
    wxXmlNode* root = doc.GetRoot();
    if (!root || root->GetName() != "CodeBlocks_project_file") {
        return profile;
    }
    
    // 查找第一个构建目标
    wxXmlNode* buildNode = root->GetChildren();
    while (buildNode) {
        if (buildNode->GetName() == "Build") {
            wxXmlNode* targetNode = buildNode->GetChildren();
            while (targetNode) {
                if (targetNode->GetName() == "Target") {
                    // 提取目标配置
                    profile.legacy.cbBuildType = targetNode->GetAttribute("title", "Debug");
                    profile.legacy.outputFilename = targetNode->GetAttribute("output", "");
                    
                    // 解析编译器选项
                    wxXmlNode* optionNode = targetNode->GetChildren();
                    while (optionNode) {
                        if (optionNode->GetName() == "Compiler") {
                            wxString options = optionNode->GetAttribute("options", "");
                            profile.legacy.cbCompilerOptions = ParseCBFlags(options);
                        } else if (optionNode->GetName() == "Linker") {
                            wxString options = optionNode->GetAttribute("options", "");
                            profile.legacy.cbLinkerOptions = ParseCBFlags(options);
                        }
                        optionNode = optionNode->GetNext();
                    }
                    break;
                }
                targetNode = targetNode->GetNext();
            }
            break;
        }
        buildNode = buildNode->GetNext();
    }
    
    profile.SyncFromLegacy();
    return profile;
}

// 工具函数实现
wxString CompatibilityBridge::ExtractVCConfiguration(const wxString& condition) {
    // 解析类似 "'$(Configuration)|$(Platform)'=='Debug|Win32'" 的条件
    int start = condition.Find("=='");
    if (start == wxNOT_FOUND) return "";
    
    start += 3;
    int end = condition.Find("|", start);
    if (end == wxNOT_FOUND) return "";
    
    return condition.Mid(start, end - start);
}

wxString CompatibilityBridge::ExtractVCPlatform(const wxString& condition) {
    int pipePos = condition.Find("|");
    if (pipePos == wxNOT_FOUND) return "";
    
    int start = pipePos + 1;
    int end = condition.Find("'", start);
    if (end == wxNOT_FOUND) return "";
    
    return condition.Mid(start, end - start);
}

std::vector<wxString> CompatibilityBridge::ParseVCFlags(const wxString& flags) {
    std::vector<wxString> result;
    wxStringTokenizer tokenizer(flags, " ;");
    while (tokenizer.HasMoreTokens()) {
        result.push_back(tokenizer.GetNextToken());
    }
    return result;
}

std::vector<wxString> CompatibilityBridge::ParseCBFlags(const wxString& flags) {
    std::vector<wxString> result;
    wxStringTokenizer tokenizer(flags, " ");
    while (tokenizer.HasMoreTokens()) {
        result.push_back(tokenizer.GetNextToken());
    }
    return result;
}

// CMake 解析（简化版）
BuildProfile CompatibilityBridge::FromCMake(const wxString& cmakeFile) {
    BuildProfile profile;
    profile.name = wxFileName(cmakeFile).GetName();
    
    wxTextFile file;
    if (file.Open(cmakeFile)) {
        for (wxString line = file.GetFirstLine(); !file.Eof(); line = file.GetNextLine()) {
            line = line.Trim();
            
            if (line.StartsWith("set(CMAKE_BUILD_TYPE")) {
                // 提取构建类型
                int start = line.Find("\"");
                int end = line.Find("\"", start + 1);
                if (start != wxNOT_FOUND && end != wxNOT_FOUND) {
                    wxString buildType = line.Mid(start + 1, end - start - 1);
                    if (buildType == "Debug") {
                        profile.variant = BuildVariant::DEBUG;
                    } else if (buildType == "Release") {
                        profile.variant = BuildVariant::RELEASE;
                    }
                }
            } else if (line.StartsWith("set(CMAKE_CXX_FLAGS")) {
                // 提取编译标志
                int start = line.Find("\"");
                int end = line.Find("\"", start + 1);
                if (start != wxNOT_FOUND && end != wxNOT_FOUND) {
                    wxString flags = line.Mid(start + 1, end - start - 1);
                    profile.legacy.cbCompilerOptions = ParseCBFlags(flags);
                }
            }
        }
    }
    
    return profile;
}

// 批量转换
std::vector<BuildProfile> CompatibilityBridge::BatchConvert(const std::vector<wxString>& projectFiles) {
    std::vector<BuildProfile> profiles;
    
    for (const auto& file : projectFiles) {
        if (wxFileExists(file)) {
            profiles.push_back(FromProjectFile(file));
        }
    }
    
    return profiles;
}

// 验证兼容性
bool CompatibilityBridge::ValidateCompatibility(const BuildProfile& profile) {
    // 检查正交属性与传统字段的一致性
    if (profile.legacy.vcConfiguration != VCMapping::VariantToConfig(profile.variant)) {
        return false;
    }
    
    if (profile.legacy.vcPlatform != VCMapping::ArchToPlatform(profile.architecture)) {
        return false;
    }
    
    if (profile.legacy.cbCompilerId != CBMapping::ToolchainToCompilerId(profile.compiler)) {
        return false;
    }
    
    return true;
}

BuildProfile CompatibilityBridge::FixCompatibilityIssues(const BuildProfile& profile) {
    BuildProfile fixed = profile;
    
    // 自动修复不一致的字段
    if (!ValidateCompatibility(profile)) {
        fixed.SyncToLegacy(); // 强制从正交属性同步传统字段
    }
    
    return fixed;
}

} // namespace cbConfig